home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
UTILFILE
/
RUN.LZH
/
RUN.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1988-04-11
|
12KB
|
355 lines
{$R-,S+,I-,D-,T-,F-,V+,B-,N-,L+ }
{$M 10000,0,0}
Program Run;
Uses DOS;
{ Useful for running a program from anywhere on a hard disk. }
{ Some programs do not work properly with the PATH command, which }
{ DOS uses to locate programs, so this one first changes to the }
{ directory where the program is located, and then runs the program. }
{ Syntax: RUN program -- finds program and runs it }
{ RUN d:program -- d: is the drive name }
{ RUN \subdir\program -- \subdir\ is a subdirectory }
{ RUN program.exe -- run the program with .EXE extension }
{ RUN program cmdline -- run the program and pass the }
{ cmdline to the program, as well }
{ Searches for the first occurrence of a program with the given name.}
{ If RUN finds the program with an extension of .COM, .EXE, or .BAT, }
{ it runs it. When that program is complete, then RUN changes the }
{ subdirectory back to the original one. }
{ If there are several programs with the same name, but different }
{ extensions, RUN chooses which one to run in the same order as }
{ MS-DOS does: }
{ 1. .COM }
{ 2. .EXE }
{ 3. .BAT }
{ You may specify the drive, or even the subdirectory where RUN }
{ should try to find your program. }
{ DO NOT attempt to run Terminate-and-Stay-Resident (TSR) programs. }
{ If you do, both RUN and the program remain in memory until you }
{ restart the computer. }
{ Returns an ERRORLEVEL code if RUN is unable to run the program. }
{ 0: RUN ran the program successfully }
{ 1: RUN could not find the program }
{ 2: RUN could not find COMMAND.COM }
{ 3: Directories nested too deeply }
Var
FoundCOM, { located a program with extension of .COM }
FoundEXE, { located a program with extension of .EXE }
FoundBAT : Boolean; { located a program with extension of .BAT }
COMloc, { location of program with extension of .COM }
EXEloc, { location of program with extension of .EXE }
BATloc : String; { location of program with extension of .BAT }
CurDir : String; { current drive and subdirectory }
Ext, { specified file extension }
Drive, { specified drive name on program }
Subdir, { specified subdirectory on program }
ProgName, { program name }
TempName, { temporary program name }
Command : String; { additional command line to pass to program }
i : Integer; { always nice to have a variable around }
oldexitproc:Pointer; { save the runtime error procedure's address }
{ ----------------------------------------------- Exists ----------- }
{ Determines if the file exists }
function Exists( FileName : String ) : Boolean;
var
SR : SearchRec;
begin
FindFirst(FileName, ReadOnly + Hidden + SysFile, SR);
Exists := (DosError = 0) and (Pos('?', FileName) = 0) and
(Pos('*', FileName) = 0);
end; { Exists }
{ ----------------------------------------------- Caps ------------- }
{ Returns the string in UPPER CASE }
function Caps( capstr : string ): string;
var i : word;
begin { Caps }
for i := 1 to Length( capstr ) do capstr[i] := UpCase( capstr[i] );
Caps := capstr;
end; { Caps }
{ ----------------------------------------------- Search ---------------- }
{ Returns path to searchfile }
function Search( subdir, searchfile : String ): String;
var
SR : SearchRec;
Ext: String[4];
begin { Search }
{ init Search }
Search := '';
{ add \ to the directory }
subdir := subdir + '\';
{ find any files in this subdir }
FindFirst( subdir+searchfile,ReadOnly + Hidden + SysFile,SR );
While DosError = 0 do begin
{ get extension }
Ext := Copy( SR.name, pos( '.', SR.name ), 4 );
If NOT FoundCOM AND (Ext = '.COM') then begin
COMloc := subdir;
FoundCOM := TRUE;
end
Else If NOT FoundEXE AND (Ext = '.EXE') then begin
EXEloc := subdir;
FoundEXE := TRUE;
end
Else If NOT FoundBAT AND (Ext = '.BAT') then begin
BATloc := subdir;
FoundBAT := TRUE;
End;
FindNext( SR );
end;
{ find any directories in this subdir and recursively call Search }
FindFirst( subdir+'*.*',Directory,SR );
While DosError = 0 do begin
If (SR.name <> '.') and (SR.name <> '..') and (SR.attr AND Directory <> 0) then
Search := Search( subdir+SR.name, searchfile );
FindNext( SR );
end;
If (Length( searchfile ) > 0) and (pos( '.', searchfile ) > 0) then
Delete( searchfile, pos( '.', searchfile ), Length( searchfile ) );
If FoundCOM then
Search := COMloc+searchfile+'.COM'
Else If FoundEXE then
Search := EXEloc+searchfile+'.EXE'
Else If FoundBAT then
Search := BATloc+searchfile+'.BAT'
Else
Search := '';
end; { Search }
{ ----------------------------------------------- GetComSpec ------------ }
function GetComSpec : string; {-Return the environment variable value}
const
ComSpec = 'COMSPEC=';
type
Env = array[0..32767] of Char;
var
EnvPtr : ^Env;
EnvStr : string;
Found : Boolean;
Len, I : Integer;
begin {GetComSpec}
GetComSpec := '';
EnvPtr := Ptr(MemW[PrefixSeg:$2C], 0);
I := 0;
Len := Length(ComSpec);
Found := False;
EnvStr := '';
repeat
if EnvPtr^[I] = #0 then begin
if EnvPtr^[Succ(I)] = #0 then
Found := True;
if Copy(EnvStr, 1, Len) = ComSpec then begin
GetComSpec := Copy(EnvStr, Succ(Len), 255);
Found := True;
end
else
EnvStr := '';
end
else
EnvStr := EnvStr+EnvPtr^[I];
Inc(I);
until Found;
end; {GetComSpec}
{ ----------------------------------------------- MyExitProc ------------ }
{$F+}
procedure MyExitProc;
begin
ExitProc := OldExitProc;
If ExitCode = 202 then begin
Writeln( 'ERROR: Subdirectories nested too deeply.' );
HALT( 3 );
end
end;
{$F-}
{ ----------------------------------------------- MAIN ------------------ }
BEGIN { RUN main program }
{ save exit proc's address }
OldExitProc := ExitProc;
ExitProc := @MyExitProc;
{ make sure we have a program to run }
If ParamCount > 0 Then begin
{ make sure we have a COMMAND shell to run }
If Exists( GetComSpec ) Then begin
{ Get Current Directory }
GetDir( 0, CurDir );
If IOresult <> 0 then
CurDir := '';
{ Get Program Name }
ProgName := Caps( ParamStr( 1 ) );
{ get drive identifier, if any }
If pos( ':', ProgName ) > 1 Then
Drive := Copy( ProgName, pos( ':', ProgName )-1, 2 )
Else begin
GetDir( 0, Drive );
If IOresult = 0 Then
Drive := copy( Drive, 1, 2 )
Else
Drive := '';
end;
{ now strip the drive identifier }
While (pos( ':', ProgName ) > 0) do
delete( ProgName, 1, pos( ':', ProgName ) );
{ get subdir identifier, if any }
SubDir := ProgName;
While (Length( SubDir ) > 0) and (SubDir[Length( SubDir )] <> '\') do
Delete( SubDir, Length( SubDir ), 1 );
{ strip directory identifiers }
While (pos( '\', ProgName ) > 0) do
delete( ProgName, 1, pos( '\', ProgName ) );
{ get file name extension, if any }
If pos( '.', ProgName ) > 0 then begin
Ext := Copy( ProgName, pos( '.', ProgName ), 4 );
If (Ext <> '.COM') and (Ext <> '.EXE') and (Ext <> '.BAT') then
Ext := '.???';
{ strip extension }
While pos( '.', ProgName ) > 0 do
Delete( ProgName, pos( '.', ProgName ), Length( ProgName ) );
end
Else begin
Ext := '.???';
End;
{ First, see if the program is where we think it is }
If Exists( Drive+SubDir+ProgName+Ext ) then
ProgName := Drive+SubDir+ProgName+Ext
Else If Exists( Drive+SubDir+ProgName+'.COM' ) then
ProgName := Drive+SubDir+ProgName+'.COM'
Else If Exists( Drive+SubDir+ProgName+'.EXE' ) then
ProgName := Drive+SubDir+ProgName+'.EXE'
Else If Exists( Drive+SubDir+ProgName+'.BAT' ) then
ProgName := Drive+SubDir+ProgName+'.BAT'
Else begin
ProgName := ProgName + '.???';
{ initialize our "find" variables for Search }
FoundCOM := FALSE;
FoundEXE := FALSE;
FoundBAT := FALSE;
TempName := Search( Drive, ProgName );
If Length( TempName ) > 0 then
ProgName := TempName;
End;
{ Verify that the program exists }
If Exists( ProgName ) Then begin
{ Build Command Line to pass to program }
Command := '';
For i := 2 To ParamCount Do
Command := Command+' '+ParamStr(i);
{ get subdir identifier, if any }
SubDir := ProgName;
While (Length( SubDir ) > 0) and (SubDir[Length( SubDir )] <> '\')
and (SubDir[Length( SubDir )] <> ':') do
Delete( SubDir, Length( SubDir ), 1 );
If (Length( SubDir ) > 3) and (SubDir[Length( SubDir )] = '\') then
Delete( SubDir, Length( SubDir ), 1 );
{ change to the proper directory }
ChDir( SubDir );
If IOresult <> 0 Then begin
Writeln( 'Invalid Subdirectory: ',SubDir );
HALT( 1 );
End;
{ Run the program }
Writeln( 'Running ',ProgName,Command );
Exec( GetComSpec,'/c '+ProgName+Command );
Case DOSerror of
0 : { do nothing } ;
2 : Writeln( 'Could Not Find ', GetComSpec );
8 : Writeln( 'Not Enough Memory' );
Else
Writeln( 'DOS Error' );
End; { Case }
{ change back to the proper directory }
ChDir( CurDir );
If IOresult <> 0 Then begin
Writeln( 'Invalid Subdirectory: ',CurDir );
HALT( 1 );
End;
end
Else begin
Writeln( 'Could not find ',Caps(ParamStr( 1 )) );
HALT( 1 );
End
end
Else begin
Writeln( 'Could not find ', GetComSpec );
HALT( 2 );
End
end
Else begin
Writeln( 'Syntax: RUN program -- finds program and runs it' );
Writeln( ' RUN d:program -- d: is the drive name' );
Writeln( ' RUN \subdir\program -- \subdir\ is a subdirectory' );
Writeln( ' RUN program.exe -- run the program with .EXE extension' );
Writeln( ' RUN program cmdline -- run the program and pass the' );
Writeln( ' cmdline to the program, as well' );
HALT( 1 );
End;
END. { RUN main program }